package com.acme.bankapp.service.bank;

import java.util.Arrays;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import com.acme.bankapp.domain.bank.account.Account;
import com.acme.bankapp.domain.bank.client.Client;
import com.acme.bankapp.domain.bank.client.Gender;
import com.acme.bankapp.service.bank.exception.NotEnoughFundsException;
import com.acme.bankapp.service.bank.exception.OverDraftLimitExceededException;
import com.acme.bankapp.service.email.EmailService;
import com.acme.bankapp.test.TestApplication;

public class BankApplication {

	private static final String KEY_FOR_SERIALIZATION_FILE = "-loadbank";

	private static final String KEY_FOR_SERVER = "-server";

	private static final String KEY_FOR_STATISTICS = "-statistics";

	public static final double MAX_BALANCE = 100;

	enum TypeOperation {
		DEPOSIT_OF_FUNDS,
		WITHDRAWAL_OF_FUNDS
	}

	/**
	 * @param args
	 * @throws Exception
	 */
	public static void main(String[] args) throws Exception {
		Bank someBank = null;

		int index =	Arrays.binarySearch(args, KEY_FOR_SERIALIZATION_FILE);
		if (index >= 0) {
			someBank = BankService.readBank();
		} else {
			someBank = TestApplication.getTestBank();
			TestApplication.fillTestBank(someBank);
		}

		index = Arrays.binarySearch(args, KEY_FOR_SERVER);
		if (index >= 0) {
			BankServer.startServer(someBank);
		}

		index = Arrays.binarySearch(args, KEY_FOR_STATISTICS);
		if (index >= 0) {
			BankReport.getNbOfCustomers(someBank);
			BankReport.getNbOfAccounts(someBank);
			BankReport.getAccountSortedBySum(someBank);
			BankReport.getBankCredit(someBank);
			Map<Client, Account[]> map = BankReport.getCustomerAccount(someBank);
			for (Client client : map.keySet()) {
				Account[] accounts = map.get(client);
				System.out.print(client.getClientSalution() + ":");
				for (Account account : accounts) {
					System.out.print(" " + account);
				}
			}
		}

		EmailService.getEmailService().close();
		System.out.println("call close");
		someBank.addClient(new Client("Test", Gender.FEMALE));
	}

	public static void modifyBank(Bank bank, int clientId, int accountId, TypeOperation type, double diffBalance) {
		try {
			Set<Client> clients = bank.getClients();
			Iterator<Client> iteratorClients = clients.iterator();
			for (int i = 0; i < clientId && iteratorClients.hasNext(); i++) {
				iteratorClients.next();
			}
			Set<Account> accounts = iteratorClients.next().getAccounts();
			Iterator<Account> iteratorAccounts = accounts.iterator();
			for (int i = 0; i < accountId && iteratorAccounts.hasNext(); i++) {
				iteratorAccounts.next();
			}
			Account account = iteratorAccounts.next();
			switch (type) {
			case DEPOSIT_OF_FUNDS:
				account.deposit(diffBalance);
				break;
			case WITHDRAWAL_OF_FUNDS:
				account.withdraw(diffBalance);
			}
		} catch (IllegalArgumentException exception) {
			System.out.println(exception.getMessage());
		} catch (OverDraftLimitExceededException exception) {
			System.out.println(exception.getMessage());
		} catch (NotEnoughFundsException exception) {
			System.out.println(exception.getMessage());
		}
	}
}
